import  { forwardRef, useImperativeHandle, useRef } from 'react';
import CodeBlock from "../../../component/CodeBlock";

const ForwardRefExample = () => {
    // 子组件通过forwardRef转发ref
    const ChildComponent = forwardRef((_props, ref) => {
        const inputRef = useRef<HTMLInputElement>(null);
        
        // 使用useImperativeHandle自定义暴露给父组件的实例值
        useImperativeHandle(ref, () => ({
            focus: () => {
                inputRef.current?.focus();
            },
            getValue: () => {
                return inputRef.current?.value || '';
            },
            setValue: (value: string) => {
                if (inputRef.current) {
                    inputRef.current.value = value;
                }
            }
        }));

        return (
            <div style={{ 
                border: '1px solid #e0e0e0', 
                borderRadius: '8px', 
                padding: '16px', 
                marginTop: '16px',
                backgroundColor: '#f9f9f9'
            }}>
                <p style={{ 
                    fontWeight: 'bold', 
                    color: '#333',
                    marginBottom: '8px'
                }}>子组件</p>
                <input 
                    ref={inputRef} 
                    type="text" 
                    placeholder="请输入内容" 
                    style={{ 
                        padding: '8px', 
                        borderRadius: '4px', 
                        border: '1px solid #ccc', 
                        width: '100%',
                        boxSizing: 'border-box'
                    }} 
                />
            </div>
        );
    });

    // 父组件
    const ParentComponent = () => {
        const childRef = useRef<{ 
            focus: () => void; 
            getValue: () => string; 
            setValue: (value: string) => void 
        }>(null);

        const handleFocus = () => {
            childRef.current?.focus();
        };

        const handleGetValue = () => {
            const value = childRef.current?.getValue();
            alert(`子组件input的值为: ${value}`);
        };

        const handleSetValue = () => {
            childRef.current?.setValue('Hello from Parent!');
        };

        return (
            <div style={{ 
                border: '1px solid #ddd', 
                borderRadius: '8px', 
                padding: '20px', 
                backgroundColor: '#fff',
                boxShadow: '0 2px 4px rgba(0,0,0,0.1)'
            }}>
                <h3 style={{ 
                    color: '#2c3e50',
                    borderBottom: '2px solid #3498db',
                    paddingBottom: '8px',
                    marginBottom: '16px'
                }}>父组件</h3>
                <div style={{ marginBottom: '16px' }}>
                    <button 
                        onClick={handleFocus}
                        style={{
                            backgroundColor: '#3498db',
                            color: 'white',
                            border: 'none',
                            padding: '8px 16px',
                            borderRadius: '4px',
                            cursor: 'pointer',
                            marginRight: '8px',
                            marginBottom: '8px'
                        }}
                    >
                        聚焦子组件input
                    </button>
                    <button 
                        onClick={handleGetValue}
                        style={{
                            backgroundColor: '#2ecc71',
                            color: 'white',
                            border: 'none',
                            padding: '8px 16px',
                            borderRadius: '4px',
                            cursor: 'pointer',
                            marginRight: '8px',
                            marginBottom: '8px'
                        }}
                    >
                        获取子组件input值
                    </button>
                    <button 
                        onClick={handleSetValue}
                        style={{
                            backgroundColor: '#e74c3c',
                            color: 'white',
                            border: 'none',
                            padding: '8px 16px',
                            borderRadius: '4px',
                            cursor: 'pointer',
                            marginRight: '8px',
                            marginBottom: '8px'
                        }}
                    >
                        设置子组件input值
                    </button>
                </div>
                <ChildComponent ref={childRef} />
            </div>
        );
    };

    const codeExample = `
// 子组件通过forwardRef转发ref
const ChildComponent = forwardRef((props, ref) => {
    const inputRef = useRef<HTMLInputElement>(null);
    
    // 使用useImperativeHandle自定义暴露给父组件的实例值
    useImperativeHandle(ref, () => ({
        focus: () => {
            inputRef.current?.focus();
        },
        getValue: () => {
            return inputRef.current?.value || '';
        },
        setValue: (value: string) => {
            if (inputRef.current) {
                inputRef.current.value = value;
            }
        }
    }));

    return (
        <div>
            <p>子组件</p>
            <input ref={inputRef} type="text" placeholder="请输入内容" />
        </div>
    );
});

// 父组件
const ParentComponent = () => {
    const childRef = useRef<{ 
        focus: () => void; 
        getValue: () => string; 
        setValue: (value: string) => void 
    }>(null);

    const handleFocus = () => {
        childRef.current?.focus();
    };

    const handleGetValue = () => {
        const value = childRef.current?.getValue();
        alert(\`子组件input的值为: \${value}\`);
    };

    const handleSetValue = () => {
        childRef.current?.setValue('Hello from Parent!');
    };

    return (
        <div>
            <h3>父组件</h3>
            <button onClick={handleFocus}>聚焦子组件input</button>
            <button onClick={handleGetValue}>获取子组件input值</button>
            <button onClick={handleSetValue}>设置子组件input值</button>
            <ChildComponent ref={childRef} />
        </div>
    );
};`;

    return (
        <div style={{ 
            maxWidth: '800px', 
            margin: '0 auto', 
            padding: '20px',
            fontFamily: 'Arial, sans-serif'
        }}>
            <h2 style={{ 
                color: '#2c3e50',
                textAlign: 'center',
                marginBottom: '20px'
            }}>forwardRef 用法</h2>
            <p style={{ 
                lineHeight: '1.6',
                color: '#34495e'
            }}>forwardRef 是 React 中的一个高阶组件，用于将 ref 从父组件转发到子组件的 DOM 元素或类组件实例。</p>
            <p style={{ 
                lineHeight: '1.6',
                color: '#34495e'
            }}>默认情况下，ref 不能作为 props 传递，也不能在函数组件中使用，因为函数组件没有实例。通过 forwardRef，我们可以将 ref 转发到子组件内部的元素上。</p>
            
            <h3 style={{ 
                color: '#2c3e50',
                borderBottom: '1px solid #eee',
                paddingBottom: '8px'
            }}>使用场景</h3>
            <ul style={{ 
                lineHeight: '1.8',
                color: '#34495e'
            }}>
                <li>父组件需要直接访问子组件的 DOM 元素</li>
                <li>父组件需要调用子组件暴露的方法</li>
                <li>实现焦点管理、动画触发等需要直接操作 DOM 的功能</li>
            </ul>

            <h3 style={{ 
                color: '#2c3e50',
                borderBottom: '1px solid #eee',
                paddingBottom: '8px'
            }}>示例：父组件调用子组件元素</h3>
            <p style={{ 
                lineHeight: '1.6',
                color: '#34495e'
            }}>以下示例展示了父组件如何通过 ref 调用子组件中的 input 元素，实现聚焦、获取值和设置值的功能：</p>
            
            <ParentComponent />
            
            <div style={{ marginTop: '24px' }}>
                <CodeBlock code={codeExample} />
            </div>
        </div>
    );
};

export default ForwardRefExample;